Skip to content

feat(workspaces-sync): auto-publish from codemux-remote hosts#46

Merged
Zeus-Deus merged 1 commit into
mainfrom
debug-remote-device-sync
May 28, 2026
Merged

feat(workspaces-sync): auto-publish from codemux-remote hosts#46
Zeus-Deus merged 1 commit into
mainfrom
debug-remote-device-sync

Conversation

@Zeus-Deus
Copy link
Copy Markdown
Owner

Summary

  • Workspaces an agent creates directly on a host (via the MCP workspace_create tool, or codemux-remote workspace register) now surface in every dev device's overview within ~90s without an explicit push from any laptop.
  • Deliberately asymmetric: codemux-app dev devices keep their existing manual push/pull (preserves the "close laptop, continue in cloud" flow + user agency); codemux-remote hosts auto-publish because they're always-on and exist to be used as hosts.
  • New pull-conflict guard refuses to clobber a local workspace already on the same branch + project ((basename(project_path), git_branch) match).

Pipeline

  1. New codemux-remote workspace list [--state-dir] CLI reads the daemon's SQLite directly (no running daemon required) and prints {host_id, workspaces[]}.
  2. New hosts_inventory::spawn runs every 60s after a 12s warm-up. Per configured host with a server_id: probe (reusing the ~/.local/bin/codemux-remote PATH fallback), SSH codemux-remote workspace list, reconcile into workspaces_sync as sibling-only rows keyed by (host_server_id, origin_uid).
  3. The existing 30s workspaces_sync::push tick uploads dirty rows to the cloud, so other devices see new host-side workspaces within ~90s.

Schema

Additive ALTER TABLE workspaces_sync ADD COLUMN origin_uid TEXT. Local-only — cross-device dedupe of the same physical host workspace published by two devices simultaneously is best-effort and converges on the next pull. Documented as a known limitation in docs/features/workspaces-sync.md.

What's unchanged

Existing flow Status
Manual push / pull-back Untouched (separate code path, separate row shape)
reconcile_from_snapshot Untouched (filters to workspace_id IS NOT NULL; new sibling rows have NULL and are skipped)
Cloud pull / push Same code, same upsert helper
Pull dialog variants New SameBranchProjectBlock layered cleanly between alreadyAdopted and can_host_adopt; falls through to the same branches as before when no conflict

Test plan

  • cargo test --lib workspaces_sync:: — 19 pass (4 new for the remote-discovered helpers)
  • cargo test --lib hosts_inventory:: — 8 pass (argv lock-in, parser round-trip, reconcile insert/idempotent/rename/soft-delete/per-host scope)
  • cargo test --lib commands::workspaces_sync:: — 6 pass (conflict-guard true positives + false-positive guards)
  • cargo test --test codemux_remote_binary — 4 pass (1 new for the workspace list CLI shape)
  • cargo test --test codemux_remote_inventory — 3 pass (CLI → parser → reconcile round-trip; idempotent re-poll; rename + close propagation)
  • npm test pull-to-device-dialog — 11 pass (1 new for SameBranchProjectBlock)
  • npm run check — clean
  • cargo check --lib — clean
  • Smoke against real pandora: dev binary uploaded, serve daemon spawned, workspace registered, codemux-remote workspace list returned expected envelope, smoke artifacts cleaned up

Two pre-existing lib failures (agent_browser::resolve_binary_…, commands::mcp::project_codemux_entry_is_filtered_out) reproduce on clean main, unrelated to this change.

Workspaces an agent creates directly on a host (via the MCP
`workspace_create` tool, or a manual `codemux-remote workspace
register`) now surface in every dev device's overview without an
explicit push. The model is deliberately asymmetric: codemux-app
dev devices keep their existing manual push/pull (preserves the
"close laptop, continue in cloud" flow and user agency over what
leaves the device); codemux-remote hosts auto-publish because
they're always-on, SSH-reachable, and exist to be used as hosts.

Pipeline:
  1. `codemux-remote workspace list` CLI reads the daemon's SQLite
     directly and prints `{host_id, workspaces[]}`. Works even when
     the daemon isn't running.
  2. `hosts_inventory::spawn` runs every 60s after a 12s warm-up;
     per configured host with a server_id it probes (reusing the
     `~/.local/bin/codemux-remote` PATH fallback), SSHes
     `codemux-remote workspace list`, and reconciles into
     `workspaces_sync` as sibling-only rows keyed by
     `(host_server_id, origin_uid)`.
  3. The existing 30s push tick uploads dirty rows to the cloud, so
     other devices see new host-side workspaces within ~90s.

Pull-conflict guard: `AdoptionPreview.same_branch_project_exists_at`
points at the local workspace_id when another local workspace
matches `(basename(project_path), git_branch)` with the remote row.
The dialog renders SameBranchProjectBlock with an "Open the
existing workspace" CTA and hides Pull, so a pull can't silently
clobber work the user is already doing locally.

Schema: additive `ALTER TABLE workspaces_sync ADD COLUMN origin_uid
TEXT`. Local-only — cross-device dedupe for the same physical host
workspace published by two devices simultaneously is best-effort
and converges on the next pull. Tracked as a known limitation.

Touches:
- src-tauri/src/bin/codemux_remote.rs: `workspace list` subcommand
- src-tauri/src/database.rs: origin_uid column + 5 helpers
- src-tauri/src/hosts_inventory.rs: new poller + reconcile
- src-tauri/src/lib.rs: spawn the poller
- src-tauri/src/commands/workspaces_sync.rs: conflict detection
- src/components/workspaces-overview/pull-to-device-dialog.tsx:
  SameBranchProjectBlock variant
- docs/features/workspaces-sync.md, remote-hosts.md: design
  rationale + identity contract + known limitations

Tests: 33 new unit tests across DB helpers, parser, reconcile,
conflict detection, and dialog variant; 3 new CLI/parse/reconcile
integration tests in tests/codemux_remote_inventory.rs; CLI
shape contract test in tests/codemux_remote_binary.rs. Smoke-
verified against a real codemux-remote on pandora.
@Zeus-Deus Zeus-Deus merged commit 6a3f9e3 into main May 28, 2026
3 of 4 checks passed
@Zeus-Deus Zeus-Deus deleted the debug-remote-device-sync branch May 28, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant